{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# TransE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "\n",
    "#### for word2vec:\n",
    "https://towardsdatascience.com/implementing-word2vec-in-pytorch-skip-gram-model-e6bae040d2fb\n",
    "#### for transD:\n",
    "https://github.com/jimmywangheng/knowledge_representation_pytorch/\n",
    "#### for RNN:\n",
    "https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:02:43.660498Z",
     "start_time": "2019-07-06T08:02:42.927604Z"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "from collections import defaultdict, Counter\n",
    "import networkx as nx\n",
    "import numpy as np\n",
    "import pylab as plt\n",
    "import random\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "from copy import deepcopy\n",
    "from torch import optim\n",
    "import torch.nn.functional as F\n",
    "from torch.autograd import Variable\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:02:44.850688Z",
     "start_time": "2019-07-06T08:02:44.843279Z"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "def marginLoss(pos, neg, margin):\n",
    "    return torch.sum(torch.max(pos - neg + margin, torch.zeros(pos.size())))\n",
    "\n",
    "def getBatchList(tripleList, num_batches):\n",
    "    l = len(tripleList) // num_batches # batch_size\n",
    "    v = []\n",
    "    for i in range(num_batches-1):\n",
    "        v.append(tripleList[l*i:l*(i+1)])\n",
    "    v.append(tripleList[l*(num_batches-1):])\n",
    "    return v\n",
    "\n",
    "def getBatch_raw_all(tripleList):\n",
    "    ph, pt ,pr = np.array(tripleList).T\n",
    "    k=int(len(tripleList)/2)\n",
    "    newTripleList=deepcopy(tripleList)\n",
    "    np.random.shuffle(newTripleList[:k,0])# corrupt head/tail for half of data\n",
    "    np.random.shuffle(newTripleList[k:,-1])\n",
    "    nh, nt, nr = np.array(newTripleList).T\n",
    "    return ph, pt, pr, nh, nt, nr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:02:45.612015Z",
     "start_time": "2019-07-06T08:02:45.604552Z"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "class transE(nn.Module):\n",
    "\n",
    "    def __init__(self, entity_total, relation_total, embedding_size):\n",
    "        super(transE, self).__init__()\n",
    "        \n",
    "        self.eE = nn.Embedding(entity_total, embedding_size) #embed entities\n",
    "        self.rE = nn.Embedding(relation_total, embedding_size) #embed relation(s)\n",
    "\n",
    "    def forward(self, pos_h, pos_t, pos_r, neg_h, neg_t, neg_r):\n",
    "        \n",
    "        pos_h_e = self.eE(pos_h)\n",
    "        pos_t_e = self.eE(pos_t)\n",
    "        pos_r_e = self.rE(pos_r)\n",
    "        neg_h_e = self.eE(neg_h)\n",
    "        neg_t_e = self.eE(neg_t)\n",
    "        neg_r_e = self.rE(neg_r)\n",
    "        \n",
    "        pos = torch.sum((pos_h_e + pos_r_e - pos_t_e) ** 2, 1)\n",
    "        neg = torch.sum((neg_h_e + neg_r_e - neg_t_e) ** 2, 1)\n",
    "        return pos, neg\n",
    "    \n",
    "    def get_eE(self, inputs):\n",
    "        return self.eE(inputs)\n",
    "\n",
    "    def get_rE(self, inputs):\n",
    "        return self.rE(inputs)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:02:53.670816Z",
     "start_time": "2019-07-06T08:02:53.658960Z"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "# parameters\n",
    "num_batches=100\n",
    "embedding_size=2\n",
    "entity_total=10\n",
    "relation_total=1\n",
    "sample_size = 10000\n",
    "pairs=list(zip(range(9),[0]*10,range(1,10)))\n",
    "trainList=np.array(random.choices(pairs,k=sample_size))\n",
    "trainBatchList = getBatchList(trainList, num_batches)\n",
    "model = transE(entity_total, relation_total, embedding_size)\n",
    "optimizer = optim.SGD(model.parameters(), lr=0.01) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:10:16.372770Z",
     "start_time": "2019-07-06T08:10:16.369021Z"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "100"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(trainBatchList)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:03:00.770272Z",
     "start_time": "2019-07-06T08:03:00.765162Z"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0, 0, 1),\n",
       " (1, 0, 2),\n",
       " (2, 0, 3),\n",
       " (3, 0, 4),\n",
       " (4, 0, 5),\n",
       " (5, 0, 6),\n",
       " (6, 0, 7),\n",
       " (7, 0, 8),\n",
       " (8, 0, 9)]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pairs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:10:36.406180Z",
     "start_time": "2019-07-06T08:10:30.048137Z"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loss at epo 0: 19.019951581954956\n",
      "Loss at epo 10: 12.78\n",
      "Loss at epo 20: 12.06\n"
     ]
    }
   ],
   "source": [
    "# model and training\n",
    "num_epochs = 30\n",
    "Loss=[]\n",
    "for epo in range(num_epochs):\n",
    "    loss_val = 0\n",
    "    random.shuffle(trainBatchList)\n",
    "    for batchList in trainBatchList:\n",
    "        #\n",
    "        optimizer.zero_grad()\n",
    "        #\n",
    "        pos_h_batch, pos_r_batch, pos_t_batch,  neg_h_batch, neg_r_batch , neg_t_batch\\\n",
    "        = getBatch_raw_all(batchList)\n",
    "        pos_h_batch = Variable(torch.LongTensor(pos_h_batch))\n",
    "        pos_t_batch = Variable(torch.LongTensor(pos_t_batch))\n",
    "        pos_r_batch = Variable(torch.LongTensor(pos_r_batch))\n",
    "        neg_h_batch = Variable(torch.LongTensor(neg_h_batch))\n",
    "        neg_t_batch = Variable(torch.LongTensor(neg_t_batch))\n",
    "        neg_r_batch = Variable(torch.LongTensor(neg_r_batch))\n",
    "        pos, neg = model(pos_h_batch, pos_t_batch, pos_r_batch,\\\n",
    "                         neg_h_batch, neg_t_batch, neg_r_batch)\n",
    "        losses = marginLoss(pos, neg, 1)        \n",
    "        loss_val += losses.item()\n",
    "        losses.backward()\n",
    "        optimizer.step()\n",
    "        \n",
    "    \n",
    "    if epo % 10 == 0:    \n",
    "        print(f'Loss at epo {epo}: {loss_val/len(trainBatchList)}')\n",
    "    Loss.append(loss_val/len(trainBatchList))        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:10:38.646967Z",
     "start_time": "2019-07-06T08:10:38.496672Z"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'Loss')"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(Loss,color='RoyalBlue',marker='o')\n",
    "plt.xlabel('N of epochs',fontsize=16)\n",
    "plt.ylabel('Loss',fontsize=16)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-06T08:10:46.467134Z",
     "start_time": "2019-07-06T08:10:46.284506Z"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 360x360 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "posR=dict(zip(range(10),model.get_rE(Variable(torch.LongTensor([0]))).data.numpy()))\n",
    "posE=dict(zip(range(10),model.get_eE(Variable(torch.LongTensor(range(10)))).data.numpy()))\n",
    "#\n",
    "fig = plt.figure(figsize=(5, 5),facecolor='white')\n",
    "ax = fig.add_subplot(111)\n",
    "plt.title('Entity and relation',fontsize=16)\n",
    "#\n",
    "x,y=posR[0]\n",
    "plt.plot(0,0,'ro')\n",
    "plt.plot(x,y,'rx')\n",
    "plt.plot([0,x],[0,y],'r-')\n",
    "#\n",
    "for i in range(9):\n",
    "    x,y=posE[i]\n",
    "    x_new,y_new=posE[i]+posR[0]\n",
    "    plt.text(x,y,i,size=14,color='green')\n",
    "    plt.text(x_new,y_new,i+1,size=14,color='gray')\n",
    "    plt.plot([x,x_new],[y,y_new],color='gray')\n",
    "    \n",
    "x,y=posE[9]\n",
    "plt.text(x,y,9,size=14,color='green')\n",
    "#\n",
    "l=6\n",
    "plt.xlim(-l,l)\n",
    "plt.ylim(-l,l)\n",
    "#\n",
    "#\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
